home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2001 May / may_2001.iso / intercd / root / Multimedia / ^DivX_Article / virtualdub / VirtualDub-source-1_4d / int128.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-03-20  |  5.9 KB  |  342 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    Copyright (C) 1998-2001 Avery Lee
  3. //
  4. //    This program is free software; you can redistribute it and/or modify
  5. //    it under the terms of the GNU General Public License as published by
  6. //    the Free Software Foundation; either version 2 of the License, or
  7. //    (at your option) any later version.
  8. //
  9. //    This program is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. //    GNU General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU General Public License
  15. //    along with this program; if not, write to the Free Software
  16. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. #include <math.h>
  19.  
  20. #include "int128.h"
  21.  
  22. const int128 __declspec(naked) int128::operator+(const int128& x) const throw() {
  23.     __asm {
  24.         push    ebx
  25.  
  26.         mov        ebx,[esp+12]
  27.         mov        edx,[esp+8]
  28.  
  29.         mov        eax,[ecx+0]
  30.         add        eax,[ebx+0]
  31.         mov        [edx+0],eax
  32.         mov        eax,[ecx+4]
  33.         adc        eax,[ebx+4]
  34.         mov        [edx+4],eax
  35.         mov        eax,[ecx+8]
  36.         adc        eax,[ebx+8]
  37.         mov        [edx+8],eax
  38.         mov        eax,[ecx+12]
  39.         adc        eax,[ebx+12]
  40.         mov        [edx+12],eax
  41.  
  42.         pop        ebx
  43.         mov        eax,[esp+4]
  44.         ret        8
  45.     }
  46. }
  47.  
  48. const int128 __declspec(naked)& int128::operator+=(const int128& x) throw() {
  49.     __asm {
  50.         mov        edx,[esp+4]
  51.  
  52.         mov        eax,[edx+0]
  53.         add        [ecx+0],eax
  54.         mov        eax,[edx+4]
  55.         adc        [ecx+4],eax
  56.         mov        eax,[edx+8]
  57.         adc        [ecx+8],eax
  58.         mov        eax,[edx+12]
  59.         adc        [ecx+12],eax
  60.  
  61.         mov        eax,ecx
  62.         ret        4
  63.     }
  64. }
  65.  
  66. const int128 __declspec(naked) int128::operator-(const int128& x) const throw() {
  67.     __asm {
  68.         push    ebx
  69.  
  70.         mov        ebx,[esp+12]
  71.         mov        edx,[esp+8]
  72.  
  73.         mov        eax,[ecx+0]
  74.         sub        eax,[ebx+0]
  75.         mov        [edx+0],eax
  76.         mov        eax,[ecx+4]
  77.         sbb        eax,[ebx+4]
  78.         mov        [edx+4],eax
  79.         mov        eax,[ecx+8]
  80.         sbb        eax,[ebx+8]
  81.         mov        [edx+8],eax
  82.         mov        eax,[ecx+12]
  83.         sbb        eax,[ebx+12]
  84.         mov        [edx+12],eax
  85.  
  86.         pop        ebx
  87.         mov        eax,[esp+4]
  88.         ret        8
  89.     }
  90. }
  91.  
  92. extern "C" static void __declspec(naked) mult64x64(int128 *pDest, unsigned __int64 y, unsigned __int64 x) {
  93.     __asm {
  94.         push    ecx
  95.         mov        ecx,[esp+8]
  96.  
  97.         mov        eax,[esp+12]
  98.         mul        dword ptr [esp+20]        ;EDX:EAX = BD
  99.         mov        [ecx+0],eax
  100.         mov        [ecx+4],edx
  101.  
  102.         mov        eax,[esp+16]
  103.         mul        dword ptr [esp+24]        ;EDX:EAX = AC
  104.         mov        [ecx+8],eax
  105.         mov        [ecx+12],edx
  106.  
  107.         mov        eax,[esp+12]
  108.         mul        dword ptr [esp+24]        ;EDX:EAX = BC
  109.         add        [ecx+4],eax
  110.         adc        [ecx+8],edx
  111.  
  112.         mov        eax,[esp+16]
  113.         mul        dword ptr [esp+20]        ;EDX:EAX = AD
  114.         add        [ecx+4],eax
  115.         adc        [ecx+8],edx
  116.  
  117.         pop        ecx
  118.         ret
  119.     }
  120. }
  121.  
  122. const int128 int128::operator*(const int128& x) const throw() {
  123.     int128 ad, bc, bd;
  124.     int128 X = x.abs();
  125.     int128 Y = abs();
  126.  
  127.     mult64x64(&ad, (unsigned __int64)(X >> 64), (unsigned __int64)(Y      ));
  128.     mult64x64(&bc, (unsigned __int64)(X      ), (unsigned __int64)(Y >> 64));
  129.     mult64x64(&bd, (unsigned __int64)(X      ), (unsigned __int64)(Y      ));
  130.  
  131.     return (v[1]^x.v[1])<0 ? -(bd + ((ad + bc)<<64)) : bd + ((ad + bc)<<64);
  132. }
  133.  
  134. const int128 __declspec(naked) int128::operator<<(int v) const throw() {
  135.     __asm {
  136.         push    ebp
  137.         push    ebx
  138.         push    esi
  139.         push    edi
  140.  
  141.         mov        esi,ecx
  142.         mov        edx,[esp+20]
  143.  
  144.         mov        ecx,[esp+24]
  145.         cmp        ecx,128
  146.         ja        zeroit
  147.  
  148.         mov        eax,[esi+12]
  149.         mov        ebx,[esi+8]
  150.         mov        edi,[esi+4]
  151.         mov        ebp,[esi]
  152.  
  153. dwordloop:
  154.         cmp        ecx,32
  155.         jb        bits
  156.  
  157.         mov        eax,ebx
  158.         mov        ebx,edi
  159.         mov        edi,ebp
  160.         xor        ebp,ebp
  161.         sub        ecx,32
  162.         jmp        short dwordloop
  163.  
  164. bits:
  165.         shld    eax,ebx,cl
  166.         shld    ebx,edi,cl
  167.         mov        [edx+12],eax
  168.         mov        [edx+8],ebx
  169.         shld    edi,ebp,cl
  170.  
  171.         shl        ebp,cl
  172.         mov        [edx+4],edi
  173.         mov        [edx],ebp
  174.  
  175.         pop        edi
  176.         pop        esi
  177.         pop        ebx
  178.         pop        ebp
  179.         mov        eax,[esp+4]
  180.         ret        8
  181.  
  182. zeroit:
  183.         xor        eax,eax
  184.         mov        [edx+0],eax
  185.         mov        [edx+4],eax
  186.         mov        [edx+8],eax
  187.         mov        [edx+12],eax
  188.  
  189.         pop        edi
  190.         pop        esi
  191.         pop        ebx
  192.         pop        ebp
  193.         mov        eax,[esp+4]
  194.         ret        8
  195.     }
  196. }
  197.  
  198. const int128 __declspec(naked) int128::operator>>(int v) const throw() {
  199.     __asm {
  200.         push    ebp
  201.         push    ebx
  202.         push    esi
  203.         push    edi
  204.  
  205.         mov        esi,ecx
  206.         mov        edx,[esp+20]
  207.  
  208.         mov        ecx,[esp+24]
  209.         cmp        ecx,128
  210.         ja        zeroit
  211.  
  212.         mov        eax,[esi+12]
  213.         mov        ebx,[esi+8]
  214.         mov        edi,[esi+4]
  215.         mov        ebp,[esi]
  216.  
  217. dwordloop:
  218.         cmp        ecx,32
  219.         jb        bits
  220.  
  221.         mov        ebp,edi
  222.         mov        edi,ebx
  223.         mov        ebx,eax
  224.         sar        eax,31
  225.         sub        ecx,32
  226.         jmp        short dwordloop
  227.  
  228. bits:
  229.         shrd    ebp,edi,cl
  230.         shrd    edi,ebx,cl
  231.         mov        [edx],ebp
  232.         mov        [edx+4],edi
  233.         shrd    ebx,eax,cl
  234.  
  235.         sar        eax,cl
  236.         mov        [edx+8],ebx
  237.         mov        [edx+12],eax
  238.  
  239.         pop        edi
  240.         pop        esi
  241.         pop        ebx
  242.         pop        ebp
  243.         mov        eax,[esp+4]
  244.         ret        8
  245.  
  246. zeroit:
  247.         xor        eax,eax
  248.         mov        [edx+0],eax
  249.         mov        [edx+4],eax
  250.         mov        [edx+8],eax
  251.         mov        [edx+12],eax
  252.  
  253.         pop        edi
  254.         pop        esi
  255.         pop        ebx
  256.         pop        ebp
  257.         mov        eax,[esp+4]
  258.         ret        8
  259.     }
  260. }
  261.  
  262. const int128 __declspec(naked) int128::operator-() const throw() {
  263.     __asm {
  264.         push    ebx
  265.         push    esi
  266.         push    edi
  267.  
  268.         mov        edi,[esp+16]
  269.  
  270.         mov        eax,[ecx+12]
  271.         mov        ebx,[ecx+8]
  272.         mov        edx,[ecx+4]
  273.         mov        esi,[ecx+0]
  274.  
  275.         xor        esi,-1
  276.         xor        edx,-1
  277.         xor        ebx,-1
  278.         xor        eax,-1
  279.  
  280.         add        esi,1
  281.         adc        edx,0
  282.         adc        ebx,0
  283.         adc        eax,0
  284.  
  285.         mov        [edi+0],esi
  286.         mov        [edi+4],edx
  287.         mov        [edi+8],ebx
  288.         mov        [edi+12],eax
  289.         
  290.         mov        eax,edi
  291.         pop        edi
  292.         pop        esi
  293.         pop        ebx
  294.         ret        4
  295.     }
  296. }
  297.  
  298. const int128 __declspec(naked) int128::abs() const throw() {
  299.     __asm {
  300.         push    ebx
  301.         push    esi
  302.         push    edi
  303.  
  304.         mov        edi,[esp+16]
  305.  
  306.         mov        eax,[ecx+12]
  307.         mov        ebx,[ecx+8]
  308.         mov        edx,[ecx+4]
  309.         or        eax,eax
  310.         mov        esi,[ecx+0]
  311.         jns        positive
  312.  
  313.         xor        esi,-1
  314.         xor        edx,-1
  315.         xor        ebx,-1
  316.         xor        eax,-1
  317.  
  318.         add        esi,1
  319.         adc        edx,0
  320.         adc        ebx,0
  321.         adc        eax,0
  322.  
  323. positive:
  324.         mov        [edi+0],esi
  325.         mov        [edi+4],edx
  326.         mov        [edi+8],ebx
  327.         mov        [edi+12],eax
  328.  
  329.         mov        eax, edi
  330.         pop        edi
  331.         pop        esi
  332.         pop        ebx
  333.         ret        4
  334.     }
  335. }
  336.  
  337. int128::operator double() const throw() {
  338.     return (double)(unsigned long)v[0]
  339.         + ldexp((unsigned long)((unsigned __int64)v[0]>>32), 32)
  340.         + ldexp((double)v[1], 64);
  341. }
  342.